using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Math;
using System.Xml;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using System.Security.Cryptography.X509Certificates;

namespace Pay.Core {
	public static class SecureHelper {
		//private static readonly byte[] _aeskeys = new byte[] { 0x12, 0x34, 0x56, 120, 0x90, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 120, 0x90, 0xab, 0xcd, 0xef };
		private static Regex _base64regex = new Regex(@"[A-Za-z0-9\=\/\+]");
		private static Regex _sqlkeywordregex = new Regex(@"(select|insert|delete|from|count\(|drop|table|update|truncate|asc\(|mid\(|char\(|xp_cmdshell|exec|master|net|local|group|administrators|user|or|and|-|;|,|\(|\)|\[|\]|\{|\}|%|@|\*|!|\')", RegexOptions.IgnoreCase);

		#region  aes加密解密
		/// <summary>  
		/// 获取密钥  
		/// </summary>  
		private static string Key {
			get { return @")O[NB]6,YF}+efcaj{+urifjtb>Z'e9M"; }
		}

		/// <summary>  
		/// 获取向量  
		/// </summary>  
		private static string IV {
			get { return @"L+\~f4,Ir)b$=pkf"; }
		}

		/// <summary>  
		/// AES加密  
		/// </summary>  
		/// <param name="plainStr">明文字符串</param>  
		/// <returns>密文</returns>  
		public static string AESEncrypt(string plainStr) {
			byte[] bKey = Encoding.UTF8.GetBytes(Key);
			byte[] bIV = Encoding.UTF8.GetBytes(IV);
			byte[] byteArray = Encoding.UTF8.GetBytes(plainStr);

			string encrypt = null;
			Rijndael aes = Rijndael.Create();
			using (MemoryStream mStream = new MemoryStream()) {
				using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write)) {
					cStream.Write(byteArray, 0, byteArray.Length);
					cStream.FlushFinalBlock();
					encrypt = Convert.ToBase64String(mStream.ToArray());
				}
			}
			aes.Clear();
			return encrypt;
		}

		/// <summary>  
		/// AES加密  
		/// </summary>  
		/// <param name="plainStr">明文字符串</param>  
		/// <param name="returnNull">加密失败时是否返回 null，false 返回 String.Empty</param>  
		/// <returns>密文</returns>  
		public static string AESEncrypt(string plainStr, bool returnNull) {
			string encrypt = AESEncrypt(plainStr);
			return returnNull ? encrypt : (encrypt == null ? String.Empty : encrypt);
		}

		/// <summary>  
		/// AES解密  
		/// </summary>  
		/// <param name="encryptStr">密文字符串</param>  
		/// <returns>明文</returns>  
		public static string AESDecrypt(string encryptStr) {
			byte[] bKey = Encoding.UTF8.GetBytes(Key);
			byte[] bIV = Encoding.UTF8.GetBytes(IV);
			byte[] byteArray = Convert.FromBase64String(encryptStr);

			string decrypt = null;
			Rijndael aes = Rijndael.Create();
			using (MemoryStream mStream = new MemoryStream()) {
				using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write)) {
					cStream.Write(byteArray, 0, byteArray.Length);
					cStream.FlushFinalBlock();
					decrypt = Encoding.UTF8.GetString(mStream.ToArray());
				}
			}
			aes.Clear();
			return decrypt;
		}

		/// <summary>  
		/// AES解密  
		/// </summary>  
		/// <param name="encryptStr">密文字符串</param>  
		/// <param name="returnNull">解密失败时是否返回 null，false 返回 String.Empty</param>  
		/// <returns>明文</returns>  
		public static string AESDecrypt(string encryptStr, bool returnNull) {
			string decrypt = AESDecrypt(encryptStr);
			return returnNull ? decrypt : (decrypt == null ? String.Empty : decrypt);
		}
		#endregion

		#region DES3 ECB模式  
		/// <summary>  
		/// DES3 ECB模式加密  
		/// </summary>  
		/// <param name="key">密钥：只能24位</param>  
		/// <param name="data">明文</param>  
		/// <returns>密文</returns>  
		public static string Des3EncodeECB(string key, string data) {
			try {
				var des = new TripleDESCryptoServiceProvider {
					Key = Encoding.UTF8.GetBytes(key),
					Mode = CipherMode.ECB,
					Padding = PaddingMode.PKCS7
				};
				var desEncrypt = des.CreateEncryptor();
				var buffer = Encoding.UTF8.GetBytes(data);
				return Convert.ToBase64String(desEncrypt.TransformFinalBlock(buffer, 0, buffer.Length));
			} catch (CryptographicException e) {
				Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
				return "";
			}
		}
		/// <summary>  
		/// DES3 ECB模式解密  
		/// </summary>  
		/// <param name="key">密钥</param>   
		/// <param name="data">密文</param>  
		/// <returns>明文</returns>  
		public static string Des3DecodeECB(string key, string data) {
			try {
				var des = new TripleDESCryptoServiceProvider {
					Key = Encoding.UTF8.GetBytes(key),
					Mode = CipherMode.ECB,
					Padding = PaddingMode.PKCS7
				};
				var desDecrypt = des.CreateDecryptor();
				var buffer = Convert.FromBase64String(data);
				var str_arr = desDecrypt.TransformFinalBlock(buffer, 0, buffer.Length);
				var result = Encoding.UTF8.GetString(str_arr);
				return result;
			} catch (CryptographicException e) {
				Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
				return "";
			}
		}
		#endregion

		#region 64位
		/// <summary>
		/// 解码
		/// </summary>
		/// <returns>The base64.</returns>
		/// <param name="result">Result.</param>
		public static string DecodeBase64(string result) {
			return DecodeBase64(Encoding.UTF8, result);
		}

		public static string DecodeBase64(Encoding encode, string result) {
			byte[] bytes = Convert.FromBase64String(result);
			try {
				return encode.GetString(bytes);
			} catch {
				return result;
			}
		}

		/// <summary>
		/// 编码
		/// </summary>
		/// <returns>The base64.</returns>
		/// <param name="source">Source.</param>
		public static string EncodeBase64(string source) {
			return EncodeBase64(Encoding.UTF8, source);
		}

		public static string EncodeBase64(Encoding encode, string source) {
			return Convert.ToBase64String(encode.GetBytes(source));
		}

		public static bool IsBase64String(string str) {
			if (str != null) {
				return _base64regex.IsMatch(str);
			}
			return true;
		}
		#endregion

		public static bool IsSafeSqlString(string s) {
			if ((s != null) && _sqlkeywordregex.IsMatch(s)) {
				return false;
			}
			return true;
		}

		#region md5
		public static string MD5(string inputStr) {
			byte[] buffer = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(inputStr));
			StringBuilder builder = new StringBuilder();
			foreach (byte num in buffer) {
				builder.Append(num.ToString("x").PadLeft(2, '0'));
			}
			return builder.ToString();
		}

		public static string MD5(Stream stream) {
			byte[] buffer = new MD5CryptoServiceProvider().ComputeHash(stream);
			StringBuilder builder = new StringBuilder();
			foreach (byte num in buffer) {
				builder.Append(num.ToString("x").PadLeft(2, '0'));
			}
			stream.Dispose();//文件MD5后要再读取一次，不然有异常,但不是这里释放资源的原因，不知道为什么
			return builder.ToString();
		}
		/// <summary>
		/// 获取大写的MD5签名结果
		/// </summary>
		/// <param name="encypStr"></param>
		/// <param name="charset"></param>
		/// <returns></returns>
		public static string GetMD5(string encypStr, string charset) {
			string retStr;
			MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();

			//创建md5对象
			byte[] inputBye;
			byte[] outputBye;

			//使用GB2312编码方式把字符串转化为字节数组．
			try {
				inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
			} catch {
				inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
			}
			outputBye = m5.ComputeHash(inputBye);

			retStr = BitConverter.ToString(outputBye);
			retStr = retStr.Replace("-", "").ToUpper();
			return retStr;
		}

		public static string CodeKey() {
			string times = DateTime.Now.Ticks.ToString();
			byte[] buffer = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(times));
			return Convert.ToBase64String(buffer);
		}
		#endregion

		#region RSA
		/// <summary>
		/// 生成公钥、私钥
		/// </summary>
		/// <param name="privateKey">私钥</param>
		/// <param name="publicKey">公钥</param>
		public static void Pkcs8Pem(out string privateKey, out string publicKey) {
			RsaKeyPairGenerator r = new RsaKeyPairGenerator();
			r.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
			AsymmetricCipherKeyPair keys = r.GenerateKeyPair();

			TextWriter textWriter = new StringWriter();
			PemWriter pemWriter = new PemWriter(textWriter);
			var pemObj = new Pkcs8Generator(keys.Private).Generate();
			pemWriter.WriteObject(pemObj);
			pemWriter.Writer.Flush();

			privateKey = FormatKey(textWriter.ToString(), "PRIVATE KEY");

			TextWriter textpubWriter = new StringWriter();
			PemWriter pempubWriter = new PemWriter(textpubWriter);
			pempubWriter.WriteObject(keys.Public);
			pempubWriter.Writer.Flush();

			publicKey = FormatKey(textpubWriter.ToString(), "PUBLIC KEY");
		}

		/// <summary>
		/// 生成公钥、私钥，这方法也行
		/// </summary>
		public static RSAKEY Pkcs8Pem2() {
			RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
			string xmlPrivateKey = provider.ToXmlString(true);
			string xmlPublicKey = provider.ToXmlString(false);

			var rsa = RSA.Create();
			rsa.FromXmlString(xmlPrivateKey);
			var bcKeyPair = DotNetUtilities.GetRsaKeyPair(rsa);
			var pkcs8Gen = new Pkcs8Generator(bcKeyPair.Private);
			var pemObj = pkcs8Gen.Generate();
			TextWriter textWriter = new StringWriter();
			var pemWriter = new PemWriter(textWriter);
			pemWriter.WriteObject(pemObj);
			pemWriter.Writer.Flush();
			string privateKey = FormatKey(textWriter.ToString(), "PRIVATE KEY");
			textWriter.Close();

			textWriter = new StringWriter();
			pemWriter = new PemWriter(textWriter);
			pemWriter.WriteObject(bcKeyPair.Public);
			pemWriter.Writer.Flush();
			string publicKey = FormatKey(textWriter.ToString(), "PUBLIC KEY");
			textWriter.Close();
			return new RSAKEY { PrivateKey = privateKey, PublicKey = publicKey };
		}

		/// <summary>
		/// 用JAVA私钥转成XML，再将XML私钥生成公钥
		/// </summary>
		/// <returns>The pem2.</returns>
		/// <param name="xmlPrivateKey">Xml private key.</param>
		public static RSAKEY Pkcs8Pem2(string xmlPrivateKey) {
			var rsa = RSA.Create();
			rsa.FromXmlString(xmlPrivateKey);
			var bcKeyPair = DotNetUtilities.GetRsaKeyPair(rsa);
			var pkcs8Gen = new Pkcs8Generator(bcKeyPair.Private);
			var pemObj = pkcs8Gen.Generate();
			TextWriter textWriter = new StringWriter();
			var pemWriter = new PemWriter(textWriter);
			pemWriter.WriteObject(pemObj);
			pemWriter.Writer.Flush();
			string privateKey = FormatKey(textWriter.ToString(), "PRIVATE KEY");
			textWriter.Close();

			textWriter = new StringWriter();
			pemWriter = new PemWriter(textWriter);
			pemWriter.WriteObject(bcKeyPair.Public);
			pemWriter.Writer.Flush();
			string publicKey = FormatKey(textWriter.ToString(), "PUBLIC KEY");
			textWriter.Close();
			return new RSAKEY { PrivateKey = privateKey, PublicKey = publicKey };
		}

		private static string FormatKey(string key, string delstr) {
			string header = String.Format("-----BEGIN {0}-----\\n", delstr);
			string footer = String.Format("-----END {0}-----", delstr);
			int start = key.IndexOf(header) + header.Length;
			int end = key.IndexOf(footer, start);
			key = key.Substring(start, (end - start));
			return key.Replace("\n", "");
		}

		/// <summary>
		/// KEY 结构体
		/// </summary>
		public struct RSAKEY {
			/// <summary>
			/// 公钥
			/// </summary>
			public string PublicKey {
				get;
				set;
			}
			/// <summary>
			/// 私钥
			/// </summary>
			public string PrivateKey {
				get;
				set;
			}
		}
		public static RSAKEY GetKey() {
			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
			RSAKEY item = new RSAKEY {
				PrivateKey = RsaKeyConvert.RSAPrivateKeyDotNet2Java(rsa.ToXmlString(true)),
				PublicKey = RsaKeyConvert.RSAPublicKeyDotNet2Java(rsa.ToXmlString(false))
			};

			return item;
		}

		public static RSAKEY GetKeyHex() {
			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
			RSAKEY item = new RSAKEY {
				PrivateKey = RsaKeyConvert.RSAPrivateKeyDotNet2Java2Hex(rsa.ToXmlString(true)),
				PublicKey = RsaKeyConvert.RSAPublicKeyDotNet2Java2Hex(rsa.ToXmlString(false))
			};

			return item;
		}
		#endregion

		#region 16位进制
		/// <summary>
		/// 转换到16进制
		/// </summary>
		public static string ToHex(this string s) {
			if (!string.IsNullOrEmpty(s))
				return ToHex(s, "utf-8");
			return string.Empty;
		}
		/// <summary>
		/// 转换到16进制
		/// </summary>
		/// <param name="s"></param>
		/// <param name="charset">编码,如"utf-8","gb2312"</param>
		/// <returns></returns>
		private static string ToHex(string s, string charset) {
			var chs = Encoding.GetEncoding(charset);
			byte[] bytes = chs.GetBytes(s);
			return BytesToHex(bytes);
		}
		///<summary>
		/// 从16进制转换成文本
		/// </summary>
		public static string UnHex(this string s) {
			if (!string.IsNullOrEmpty(s))
				return UnHex(s, "utf-8");
			return string.Empty;
		}
		///<summary>
		/// 从16进制转换成文本
		/// </summary>
		/// <param name="hex"></param>
		/// <param name="charset">编码,如"utf-8","gb2312"</param>
		/// <returns></returns>
		private static string UnHex(string hex, string charset = "utf-8") {
			System.Text.Encoding chs = System.Text.Encoding.GetEncoding(charset);
			return chs.GetString(Hex2Bytes(hex));
		}
		/// <summary>
		/// 转换到16进制
		/// </summary>
		public static string BytesToHex(byte[] bytes) {
			string result = string.Empty;
			//逐字节变为16进制字符
			for (int i = 0; i < bytes.Length; i++) {
				result += bytes[i].ToString("x2");
			}
			return result;
		}
		/// <summary>
		/// 16进制字符串转字节数组
		/// </summary>
		/// <returns></returns>
		public static byte[] Hex2Bytes(string hex) {
			if (hex.Length % 2 != 0) {
				hex += " ";//空格
			}
			byte[] result = new byte[hex.Length / 2];
			for (int i = 0; i < result.Length; i++) {
				result[i] = byte.Parse(hex.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
			}
			return result;
		}
		#endregion

		/// <summary>
		/// 获取文件公私钥
		/// </summary>
		/// <param name="path">文件路径</param>
		/// <param name="password">文件秘钥:hf:sft12#</param>
		/// <returns></returns>
		public static RSAKEY GetKey(string path, string password) {
			var result = new RSAKEY();
			try {
				FileStream fileStream = null;
				try {
					fileStream = new FileStream(path, FileMode.Open);
					Pkcs12Store store = new Pkcs12StoreBuilder().Build();
					store.Load(fileStream, password.ToCharArray()); //加载证书  
					string alias = null;
					foreach (string str in store.Aliases) {
						if (store.IsKeyEntry(str))
							alias = str;
					}
					AsymmetricKeyEntry keyEntry = store.GetKey(alias);
					RsaKeyParameters priKey = (RsaKeyParameters)keyEntry.Key;   //取得私钥  
					PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(priKey);
					byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
					result.PrivateKey = Convert.ToBase64String(serializedPrivateBytes);

					X509CertificateEntry certEntry = store.GetCertificate(alias);
					Org.BouncyCastle.X509.X509Certificate x509cert = certEntry.Certificate;
					RsaKeyParameters pubKey = (RsaKeyParameters)x509cert.GetPublicKey();    //取得公钥 
					SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);
					byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
					result.PublicKey = Convert.ToBase64String(serializedPublicBytes);
					//x509cert.Verify(pubKey);
				} finally {
					if (fileStream != null)
						fileStream.Close();
				}
			} catch (Exception ex) {
			}
			return result;
		}

		public static string Getkey2(string path) {
			X509Certificate2 cert = new X509Certificate2(path, "", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
			string private_key = cert.PrivateKey.ToString();
			return private_key;
		}
	}
	/// <summary>
	/// RSA密钥格式转换
	/// </summary>
	public class RsaKeyConvert {
		/// <summary>
		/// RSA私钥格式转换，java->.net
		/// </summary>
		/// <param name="privateKey">java生成的RSA私钥</param>
		/// <returns></returns>
		public static string RSAPrivateKeyJava2DotNet(string privateKey) {
			RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));

			return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
				Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
				Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
		}

		/// <summary>
		/// RSA私钥格式转换，.net->java
		/// </summary>
		/// <param name="privateKey">.net生成的私钥</param>
		/// <returns></returns>
		public static string RSAPrivateKeyDotNet2Java(string privateKey) {
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(privateKey);
			BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
			BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
			BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
			BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
			BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
			BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
			BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
			BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));

			RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);

			PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
			byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
			return Convert.ToBase64String(serializedPrivateBytes);
		}

		/// <summary>
		/// RSA公钥格式转换，java->.net
		/// </summary>
		/// <param name="publicKey">java生成的公钥</param>
		/// <returns></returns>
		public static string RSAPublicKeyJava2DotNet(string publicKey) {
			RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
			return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
				Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
				Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
		}

		/// <summary>
		/// RSA公钥格式转换，.net->java
		/// </summary>
		/// <param name="publicKey">.net生成的公钥</param>
		/// <returns></returns>
		public static string RSAPublicKeyDotNet2Java(string publicKey) {
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(publicKey);
			BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
			BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
			RsaKeyParameters pub = new RsaKeyParameters(false, m, p);

			SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
			byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
			return Convert.ToBase64String(serializedPublicBytes);
		}

		/// <summary>
		/// RSA私钥格式转换，.net->java
		/// </summary>
		/// <param name="privateKey">.net生成的私钥</param>
		/// <returns></returns>
		public static string RSAPrivateKeyDotNet2Java2Hex(string privateKey) {
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(privateKey);
			BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
			BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
			BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
			BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
			BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
			BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
			BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
			BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));

			RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);

			PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
			byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
			return SecureHelper.BytesToHex(serializedPrivateBytes);
		}

		/// <summary>
		/// RSA公钥格式转换，.net->java
		/// </summary>
		/// <param name="publicKey">.net生成的公钥</param>
		/// <returns></returns>
		public static string RSAPublicKeyDotNet2Java2Hex(string publicKey) {
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(publicKey);
			BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
			BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
			RsaKeyParameters pub = new RsaKeyParameters(false, m, p);

			SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
			byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
			return SecureHelper.BytesToHex(serializedPublicBytes);
		}
	}
}